package com.huluobo.a2203kotlinjetpackdemo.paging

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.paging.LoadState
import androidx.recyclerview.widget.LinearLayoutManager
import com.huluobo.a2203kotlinjetpackdemo.R
import com.huluobo.a2203kotlinjetpackdemo.databinding.ActivityPagingBinding
import kotlinx.coroutines.launch

/**
 * Paging总结:
 * paging:是page的进行时,也就是分页,之前SmartRefreshLayout进行下刷刷新上拉加载,都是刷新框架,用于触发页码的刷新
 * 有footer和header,来用于加载或者刷新,通过footer加载数据,page++这种情况(视频加载接口,商品加载接口,currentPage++)
 * Paging3 是google最新推出的分页加载库
 *
 * 1.Paging最关键的是数据的传递,Repo.getPagingData().cachedIn(viewModelScope) 生成一个数据流,在activity中可以通过
 *  viewModel.getPagingData().collect {
 *                 adapter.submitData(it)
 *             }来接收数据流,cachedIn(viewModelScope) 可以将请求到的数据流缓存在作用域中,如果当生命周期发生改变,可以读取这部分流进行数据填充,不需要网络加载
 *   2.通过PagingConfig来设置预加载的大小,前后翻页的key
 *   3.通过RepoPagingSource 重写load方法,加载数据
 *   4.通过RepoPagingSource 才是真正产生数据源的位置,在这当中触发了网络请求
 *   5.PagingDataAdapter 是配合paging使用的,构造中需要有个DiffUtil 来管理item中数据是否一致
 *   6.LoadStateAdapter 是一个脚布局,主要作用是有个状态LoadState,通过这个状态可以写对应的回调,类似于之前LiveData中成功和失败
 *   7.Paging给adapter传递数据的位置 adapter.submitData(it) 通过协程的flow流从viewmodel中拿到数据并填充
 */
class PagingActivity : AppCompatActivity() {
    private lateinit var dataBinding: ActivityPagingBinding

    //使用懒加载,加载viewModel
    private val viewModel by lazy {
        ViewModelProvider(this)[PagingViewMode::class.java]
    }

    private val adapter = PagingAdapter()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        dataBinding = ActivityPagingBinding.inflate(layoutInflater)
        setContentView(dataBinding.root)

        //设置刷新框架的监听器
        dataBinding.pagingSrl.setOnRefreshListener {
            //刷新框架刷新时,让adapter刷新
            adapter.refresh()
        }

        //初始化rv
        dataBinding.pagingRv.layoutManager = LinearLayoutManager(this)
        //给adapter设置读取状态适配器
        dataBinding.pagingRv.adapter = adapter.withLoadStateFooter(FooterAdapter { adapter.retry() })

        //********重点,童工协程发送和接收数据,给adapter添加数据源
        lifecycleScope.launch {
            viewModel.getPagingData().collect {
                adapter.submitData(it)
            }
        }

        adapter.addLoadStateListener {
            when (it.refresh) {
                is LoadState.NotLoading -> {
                    dataBinding.pagingRv.visibility = View.VISIBLE
                    dataBinding.pagingTv.visibility = View.GONE
                    dataBinding.pagingSrl.isRefreshing = false
                }

                is LoadState.Loading -> {
                    dataBinding.pagingRv.visibility = View.VISIBLE
                    dataBinding.pagingTv.visibility = View.GONE
                    dataBinding.pagingSrl.isRefreshing = true
                }

                is LoadState.Error -> {
                    val state = it.refresh as LoadState.Error
                    dataBinding.pagingSrl.isRefreshing = false
                    dataBinding.pagingRv.visibility = View.GONE
                    dataBinding.pagingTv.visibility = View.VISIBLE
                    dataBinding.pagingTv.text = state.error.message
                }
            }
        }

    }
}